package com.qyer.search.service;

import static org.apache.commons.dbutils.DbUtils.closeQuietly;
import static com.qyer.search.utils.DBUtils.tryConnect;

import com.qyer.search.Constants;
import com.qyer.search.cache.mutable.MutableCaches;
import com.qyer.search.filter.AbstractIDFilter;
import com.qyer.search.model.ZTagEntity;
import com.qyer.search.db.*;
import com.qyer.search.model.ZTagSnapshot;
import com.qyer.search.model.aggregation.AggregationProduct;
import com.qyer.search.model.aggregation.AggregationRegular;
import com.qyer.search.model.aggregation.Poi;
import com.qyer.search.model.aggregation.ProductProject;
import com.qyer.search.model.aggregation.VTYPEDES;
import com.qyer.search.model.middle.ExtendEntity;
import com.qyer.search.model.mutable.DoubleFaceMap;
import com.qyer.search.model.mutable.IndexMap;
import com.qyer.search.model.mutable.ProductSnapshot;
import com.qyer.search.model.mutable.QuickSearch;
import com.qyer.search.model.result.SearchEntity;
import com.qyer.search.model.result.Type1SearchEntity;
import com.qyer.search.sort.VSalesTimSorterNoSize;
import com.qyer.search.sort.VType1Sorter;
import com.qyer.search.sort.VType1Sorter2;
import com.qyer.search.utils.DotSplitUtils;
import com.qyer.search.utils.ModelUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.*;

/**
 * Created by tangzheng on 16/6/13.
 */
public class DataAccessService {
  private static class InnerHolder {
    private static final DataAccessService INSTANCE = new DataAccessService();
  }

  private DataAccessService() {
  }

  public static final DataAccessService getInstance() {
    return InnerHolder.INSTANCE;
  }

  //综合数据服务
  public ZTagSnapshot getZTags(String mix_sort_key) throws Exception{

    ZTagSnapshot zBack = MutableCaches.getInstance().Z_TAG_SNAPSHOT.getCacheContent();
    String sql = "";
    Connection conn = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    Connection conn1 = null;
    PreparedStatement pstmt1 = null;
    ResultSet rs1 = null;
    Map<Integer, ZTagEntity> zTagMap = new HashMap<>(8);
    Map<Integer, Integer> filterValues = new HashMap<>();
    Map<Integer, List<Integer>> filterValuesList = new HashMap<>();
    Set<Integer> stypes = new HashSet<>();
    Map<Integer, List<Integer>> neFilterValues = new HashMap<>();

    try {
      conn = tryConnect(MainDBResourceManager.getInstance(), "loadTags");
      sql = "select distinct channel,tag_id,parent_id,sort from qyer_lastminute.zworld_stype where parent_id != 0 and status = 1;";
      pstmt = conn.prepareStatement(sql);
      rs = pstmt.executeQuery();

      int channel,tag_id,parent_id,sort;
      while (rs.next()) {
        //channel
        channel = rs.getInt(1);
        if(!zTagMap.containsKey(channel)){
          ZTagEntity zTagEntity = new ZTagEntity();
          zTagMap.put(channel, zTagEntity);
          //System.out.println("put channel "+ channel);
        }
        //tag
        ZTagEntity zTagEntity = zTagMap.get(channel);
        tag_id = rs.getInt(2);
        stypes.add(tag_id);
        parent_id = rs.getInt(3);
        stypes.add(parent_id);
        //排序问题
        sort = rs.getInt(4);
        /*if(!zTagEntity.getOrder_STG().containsKey(parent_id)){
          zTagEntity.getOrder_STG().put(parent_id, sort);
        }*/
        if(!zTagEntity.getS_type_set().contains(tag_id)){
          zTagEntity.getS_type_set().add(tag_id);
        }
        if(!zTagEntity.getS_type_group_set().contains(parent_id)){
          zTagEntity.getS_type_group_set().add(parent_id);
        }
        if(!zTagEntity.getPositiveMap().containsKey(parent_id)){
          List<Integer> list = new ArrayList();
          list.add(tag_id);
          zTagEntity.getPositiveMap().put(parent_id, list);

          List<Integer> list1 = new ArrayList();
          list1.add(parent_id);
          zTagEntity.getNegativeMap().put(tag_id, list1);
        }else {
          zTagEntity.getPositiveMap().get(parent_id).add(tag_id);
          if(zTagEntity.getNegativeMap().containsKey(tag_id))
            zTagEntity.getNegativeMap().get(tag_id).add(parent_id);
          else{
            List<Integer> list = new ArrayList<>();
            list.add(parent_id);
            zTagEntity.getNegativeMap().put(tag_id, list);
          }
        }
      }
      //S_T_G Order
      sql = "select distinct channel,tag_id from qyer_lastminute.zworld_stype where status = 1 and parent_id = 0 order by sort;";
      pstmt = conn.prepareStatement(sql);
      rs = pstmt.executeQuery();
      int channelForOder;
      int stgForOrder;
      Map<Integer, Integer> channelOrderMap = new HashMap<>();
      while (rs.next()){
        channelForOder = rs.getInt(1);
        stgForOrder = rs.getInt(2);

        if(zTagMap.containsKey(channelForOder)){
          ZTagEntity zTagEntity = zTagMap.get(channelForOder);
          int innerOrder = 1;
          if(channelOrderMap.containsKey(channelForOder)){
            innerOrder = channelOrderMap.get(channelForOder);
          }
          if(!zTagEntity.getOrder_STG().containsKey(stgForOrder)){
            zTagEntity.getOrder_STG().put(stgForOrder, innerOrder++);
            channelOrderMap.put(channelForOder, innerOrder);
            //System.out.println("channel:"+channelForOder+";stg:"+stgForOrder+";sort:"+innerOrder);
          }
        }
      }
      //
      /*if(zTagMap.containsKey(4)){
        ZTagEntity zTagEntity = zTagMap.get(4);
        System.out.println("顺序:");
        System.out.println(zTagEntity.getOrder_STG());
      }*/
      //
      ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
      //select b.channel,b.tag_id,a.category_id,b.type from zworld_stype_category as a join (select channel,tag_id,id,type from qyer_lastminute.zworld_stype where status = 1) b on a.id = b.id;

      sql = "select distinct b.channel,b.tag_id,a.category_id,b.type from qyer_lastminute.zworld_stype_category as a join (select channel,tag_id,id,type from qyer_lastminute.zworld_stype where status = 1) b on a.stype_id = b.id;";
      pstmt = conn.prepareStatement(sql);
      rs = pstmt.executeQuery();
      int category_id;
      String type;
      while (rs.next()) {
        //channel
        channel = rs.getInt(1);
        if(zTagMap.containsKey(channel)){
          ZTagEntity zTagEntity = zTagMap.get(channel);
          tag_id = rs.getInt(2);
          category_id = rs.getInt(3);
          type = rs.getString(4);
          if("group".equals(type)){
            if(zTagEntity.getSTG_Filter().containsKey(tag_id)){
              zTagEntity.getSTG_Filter().get(tag_id).add(category_id);
            }else {
              List<Integer> list = new ArrayList();
              list.add(category_id);
              zTagEntity.getSTG_Filter().put(tag_id, list);
            }
          }else if("stype".equals(type)){
            if(zTagEntity.getST_Filter().containsKey(tag_id)){
              zTagEntity.getST_Filter().get(tag_id).add(category_id);
            }else {
              List<Integer> list = new ArrayList();
              list.add(category_id);
              zTagEntity.getST_Filter().put(tag_id, list);
            }
          }
        }

      }

      //获取上线商品的STG类型

      sql = "select distinct b.channel,a.lid,b.parent_id from (select lid,tid from qyer_lastminute.zworld_lastminute_tag where isdel = 0) a join (select tag_id,parent_id,channel from qyer_lastminute.zworld_stype where status =1 and parent_id != 0) b on a.tid = b.tag_id;";
      pstmt = conn.prepareStatement(sql);
      rs = pstmt.executeQuery();
      int lid;
      while (rs.next()) {
        channel = rs.getInt(1);
        if(zTagMap.containsKey(channel)){
          ZTagEntity zTagEntity = zTagMap.get(channel);
          lid = rs.getInt(2);
          parent_id = rs.getInt(3);
          if(zTagEntity.getProductTypeMap().containsKey(lid)){
            zTagEntity.getProductTypeMap().get(lid).add(parent_id);
          }else {
            List<Integer> list = new ArrayList<>();
            list.add(parent_id);
            zTagEntity.getProductTypeMap().put(lid, list);
          }
        }
      }
      //获取筛选项值

      sql = "select tag_id,category_id from qyer_lastminute.zworld_category_tag where state = 1 and category_id in (select distinct category_id from qyer_lastminute.zworld_stype_category);";
      pstmt = conn.prepareStatement(sql);
      rs = pstmt.executeQuery();
      while (rs.next()) {
        tag_id = rs.getInt(1);
        category_id =rs.getInt(2);
        ///////////////////////////////
        //if(tag_id == 130)
          //System.out.println("categoryId:"+category_id);
        ///////////////////////////////
        filterValues.put(tag_id, category_id);
        /////////////////////////////////////////////////////////////////////////
        if(filterValuesList.containsKey(tag_id)){
          filterValuesList.get(tag_id).add(category_id);
        }else {
          List<Integer> list = new ArrayList<>();
          list.add(category_id);
          filterValuesList.put(tag_id, list);
        }
        //////////////////////////////////////////////////////////////////////
        if(neFilterValues.containsKey(category_id)){
          neFilterValues.get(category_id).add(tag_id);

        }else {
          List<Integer> list = new ArrayList<>();
          list.add(tag_id);
          neFilterValues.put(category_id, list);
        }
      }

      //获取s_type,s_type_group 中文信息

      sql = "select tag_name,id from qyer_lastminute.zworld_tag where id in (";
      for(int id: stypes){
        sql = sql + id + ",";
      }
      sql += "-1);";
      pstmt = conn.prepareStatement(sql);
      rs = pstmt.executeQuery();
      String tag_name;
      int id;
      while (rs.next()) {
        tag_name = rs.getString(1);
        id = rs.getInt(2);
        //遍历
        Iterator<Map.Entry<Integer, ZTagEntity>> it = zTagMap.entrySet().iterator();
        while (it.hasNext()) {
          Map.Entry<Integer, ZTagEntity> entry = it.next();
          if(entry.getValue().getS_type_set().contains(id)){
            entry.getValue().getS_type_map().put(tag_name, id);
          }
          if(entry.getValue().getS_type_group_set().contains(id)){
            entry.getValue().getS_type_group_map().put(tag_name,id);
          }
        }
      }

      //获取营销标签

      sql = "select tag_id from qyer_lastminute.zworld_category_tag where category_id = 2;";
      pstmt = conn.prepareStatement(sql);
      rs = pstmt.executeQuery();
      while (rs.next()) {
        tag_id = rs.getInt(1);
        Iterator<Map.Entry<Integer, ZTagEntity>> it = zTagMap.entrySet().iterator();
        while (it.hasNext()) {
          Map.Entry<Integer, ZTagEntity> entry = it.next();
          ZTagEntity zTagEntity = entry.getValue();
          zTagEntity.getMarket_tag_Set().add(tag_id);
        }
      }

      //获取商品排序
      String sort_result = MainRedisOperator.getInstance().get(mix_sort_key);
      String[] sortStrs = sort_result.split(",");
      for(int i = 0; i < sortStrs.length; i++){
        int p_id = Integer.valueOf(sortStrs[i]);
        Set<Integer> keysets = zTagMap.keySet();
        for(int key:keysets){
          List<Integer> stg_list = zTagMap.get(key).getProductTypeMap().get(p_id);
          if(CollectionUtils.isNotEmpty(stg_list)) {
            int size = stg_list.size();
            Map<Integer,Map<Integer,Integer>> sortedMap = zTagMap.get(key).getSortedMap();
            for (int j = 0; j < size; j++) {
              int stg_id = stg_list.get(j);
              if(sortedMap.containsKey(stg_id)){
                sortedMap.get(stg_id).put(p_id, (i+1));
              }else {
                Map<Integer,Integer> tmpMap = new HashMap<>();
                tmpMap.put(p_id, (i+1));
                sortedMap.put(stg_id, tmpMap);
              }
            }
          }
        }
      }
      //获取扩展tag
      conn1 = tryConnect(DMDBResourceManager.getInstance(), "loadExtendTags");
      sql = "select channel,tag_id,tag_type from tag.lastminute_tag_extend where status = 1;";
      pstmt1 = conn1.prepareStatement(sql);
      rs1 = pstmt1.executeQuery();
      int tid;
      String category;
      while (rs1.next()){

        channel = rs1.getInt(1);
        if(zTagMap.containsKey(channel)) {
          ZTagEntity zTagEntity = zTagMap.get(channel);
          tid = rs1.getInt(2);
          category = rs1.getString(3);
          if("stype".equals(category)){
            zTagEntity.getExtend_st().add(tid);
          }else {
            zTagEntity.getExtend_stg().add(tid);
          }
        }
        //System.out.println("EXTEND");
      }
      ///可扩展半tag
      ZTagEntity zTagEntity;
      Map<Integer, List<Integer>> stype_stg_map;
      Set<Integer> stype_set;
      Set<Integer> stg_set;
      List<Integer> stg_list;
      Map<Integer, List<ExtendEntity>> extendE;
      Iterator<Map.Entry<Integer, ZTagEntity>> iterator = zTagMap.entrySet().iterator();
      while (iterator.hasNext()){
        Map.Entry<Integer, ZTagEntity> entry = iterator.next();
        channel = entry.getKey();
        zTagEntity = entry.getValue();
        stype_stg_map = zTagEntity.getNegativeMap();
        if(MapUtils.isNotEmpty(stype_stg_map)){
          extendE = zTagEntity.getExtend_half();
          stg_set = zTagEntity.getExtend_stg();
          stype_set = zTagEntity.getExtend_st();
          for(int vs : stype_set){
            if(stype_stg_map.containsKey(vs)){
              stg_list = stype_stg_map.get(vs);
              for(int stg:stg_list){
                if(!stg_set.contains(stg)){
                  if(extendE.containsKey(stg)){
                    List<ExtendEntity> list = extendE.get(stg);
                    list.add(new ExtendEntity(stg, vs));
                  }else {
                    List<ExtendEntity> list = new ArrayList<>();
                    list.add(new ExtendEntity(stg, vs));
                    extendE.put(stg, list);
                  }
                }
              }
            }
          }
        }
      }

      //System.out.println(zTagMap);
      //返回结果
      //////////////////////////////////////////////////////////////////////////////////new cache
      /////
      //////////////////////////////////////////////////////////////////////////////////new cache


      return new ZTagSnapshot(filterValues, zTagMap, neFilterValues)
                                              .setFilterValuesList(filterValuesList).setIsOk(true);
    }catch (Exception e){
      e.printStackTrace();
      return zBack;
    }
    finally {
      closeQuietly(conn, pstmt, rs);
      closeQuietly(conn1, pstmt1, rs1);
    }
  }


  public ProductSnapshot getProducts(String time){

    //System.out.println("Start Time:"+time);
    long t1 = System.currentTimeMillis();
    ProductSnapshot productSnapshot = new ProductSnapshot();
    ProductSnapshot back = MutableCaches.getInstance().P_SNAPSHOT.getCacheContent();

    String sql = "";
    Connection conn = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;

    int id = 0;
    int travel_day = 0;
    int tid = 0;
    int parentId = 0;
    int channel = 0;
    int category_id = 0;
    String type;
    String tagName;
    String abroad;
    String start_city_Ids;
    String continentIds;
    String countryIds;
    String cityids;
    String poiIds;
    String channels;
    long travel_starttime;
    long travel_endtime;
    long onsale_time;

    List<Integer> continentList;
    List<Integer> countryList;
    List<Integer> cityList;
    List<Integer> poiList;
    List<Integer> start_cityList;
    List<Integer> channelList;
    List<Integer> setOutPlace;

    Map<Integer, Integer> travelDayMap = new HashMap<>();
    Map<Integer, String> tagInfo = new HashMap<>();
    Map<Integer, String> poiInfo = new HashMap<>();

    try {

      Map<Integer, Integer> country_continent = MutableCaches.getInstance()
        .COUNTRY_CONTINENT_ID_MAP.getCacheContent();
      Map<Integer, Integer> city_country = MutableCaches.getInstance()
        .CITY_COUNTRY_ID_MAP.getCacheContent();
      ZTagSnapshot zTagSnapshot = MutableCaches.getInstance().Z_TAG_SNAPSHOT.getCacheContent();
      DoubleFaceMap doubleFaceMap = MutableCaches.getInstance().CONTINENT_DICT.getCacheContent();

      try {
        while ((MapUtils.isEmpty(country_continent)) || (MapUtils.isEmpty(city_country)
        ) || (zTagSnapshot == null) || (doubleFaceMap == null)) {
          Thread.sleep(1000);
          country_continent = MutableCaches.getInstance().COUNTRY_CONTINENT_ID_MAP.getCacheContent();
          city_country = MutableCaches.getInstance().CITY_COUNTRY_ID_MAP.getCacheContent();
          zTagSnapshot = MutableCaches.getInstance().Z_TAG_SNAPSHOT.getCacheContent();
          doubleFaceMap = MutableCaches.getInstance().CONTINENT_DICT.getCacheContent();
          System.out.println("SLEEP");

        }
      }catch (Exception e){
        e.printStackTrace();
      }
      //Thread.sleep(1000*60);
      //System.out.println("SLEEP GO");


      conn = tryConnect(MainDBResourceManager.getInstance(), "loadProducts");

      sql = "select id,travelday from qyer_lastminute.lastminute_extend;";
      pstmt = conn.prepareStatement(sql);
      rs = pstmt.executeQuery();
      while (rs.next()) {
        id = rs.getInt(1);
        travel_day = rs.getInt(2);
        travelDayMap.put(id, travel_day);
      }



      Map<Integer,List<Integer>> filterTagMap = zTagSnapshot.getFilterValuesList();
      Map<Integer, ZTagEntity> zTagEntityMap = zTagSnapshot.getvStypeMap();
      Map<Integer, List<Integer>> neFilterMap = zTagSnapshot.getNeFilterValues();

      Set<Integer> stypes = new HashSet<>();
      Set<Integer> markets = zTagSnapshot.getvStypeMap().get(1).getMarket_tag_Set();
      ///////////////////////////////////////////////////////////////////////////////////////
      //System.out.println("market:"+markets);
      ////////////////////////////////////////////////////////////////////////////////////////
      Set<Integer> tags = new HashSet<>();
      tags.addAll(markets);
      tags.addAll(filterTagMap.keySet());
      stypes.addAll(tags);
      List<Integer> allPoi = new ArrayList<>();
      //Map<Integer, String> marketTagsName = new HashMap<>();

      Map<Integer, List<QuickSearch>> quickSearchMap = new HashMap<>();
      Map<Integer, Set<String>> city_p = productSnapshot.getCity_product();
      Map<Integer, Set<String>> country_p = productSnapshot.getCountry_product();
      Map<Integer, Set<String>> continent_p = productSnapshot.getContinent_product();

      /////////////////////////////////
      sql = "select id,abroad,start_cityid,continent,countryids,cityids,poi,channel,travel_starttime,travel_endtime,onsale_time,sort_list_price,sort_sold_num from qyer_lastminute.lastminute_main where onsale = 1 and status = 0 and title != '';";
      pstmt = conn.prepareStatement(sql);
      rs = pstmt.executeQuery();
      while (rs.next()){
        id = rs.getInt(1);
        abroad = rs.getString(2);
        start_city_Ids = rs.getString(3);
        continentIds = rs.getString(4);
        countryIds = rs.getString(5);
        cityids = rs.getString(6);
        poiIds = rs.getString(7);
        channels = rs.getString(8);
        travel_starttime = rs.getLong(9);
        travel_endtime = rs.getLong(10);
        onsale_time = rs.getLong(11);

        setOutPlace = DotSplitUtils.splitToIntList(abroad, Constants.START_POS_MAP);
        //start_cityList = DotSplitUtils.splitToIntList(start_city_Ids);
        start_cityList = DotSplitUtils.splitToIntList2(start_city_Ids, id);
        //continentList = DotSplitUtils.splitToIntList(continentIds);
        continentList = DotSplitUtils.splitToIntList2(continentIds, id);
        for(int idForContinent:continentList){
          if(doubleFaceMap.getObverseDict().containsKey(idForContinent)){
            if(continent_p.containsKey(idForContinent)){
              continent_p.get(idForContinent).add(String.valueOf(id));
            }else {
              Set<String> set = new HashSet<>(1024);
              set.add(String.valueOf(id));
              continent_p.put(idForContinent, set);
            }
          }
        }
        //countryList = DotSplitUtils.splitToIntList(countryIds);
        countryList = DotSplitUtils.splitToIntList2(countryIds, id);
        //------------------------------------------------------------------------//
        for(int idForCountry:countryList){
          if(Constants.HOT_COUNTRY.contains(idForCountry)){
            if(country_p.containsKey(idForCountry)){
              country_p.get(idForCountry).add(String.valueOf(id));
            }else {
              Set<String> set = new HashSet<>(1500);
              set.add(String.valueOf(id));
              country_p.put(idForCountry, set);
            }
          }
        }
        //------------------------------------------------------------------------//
        //cityList = DotSplitUtils.splitToIntList(cityids);
        cityList = DotSplitUtils.splitToIntList2(cityids, id);
        //------------------------------------------------------------------------//
        /*for(int idForCity:cityList){
          if(Constants.HOT_CITY.contains(idForCity)){
            if(city_p.containsKey(idForCity)){
              city_p.get(idForCity).add(String.valueOf(id));
            }else {
              Set<String> set = new HashSet<>(1024);
              set.add(String.valueOf(id));
              city_p.put(idForCity, set);
            }
          }
        }*/
        //------------------------------------------------------------------------//
        //poiList = DotSplitUtils.splitToIntList(poiIds);
        poiList = DotSplitUtils.splitToIntList2(poiIds, id);
        allPoi.addAll(poiList);
        channelList = DotSplitUtils.splitToIntList(channels, Constants.ChannelMap);

        ProductProject productProject = new ProductProject(id);
        productProject.setChannel(channelList);
        productProject.consDest(continentList, countryList, cityList, city_country,
                                country_continent);
        productProject.setSetOutPlace(setOutPlace);
        productProject.setStartCity(start_cityList);
        productProject.setT_end_time(travel_endtime);
        productProject.setT_start_time(travel_starttime);
        productProject.setOn_sale_time(onsale_time);
        productProject.setPoiList(poiList);
        if(travelDayMap.containsKey(id)){
          productProject.setTravel_day(travelDayMap.get(id));
        }


        productSnapshot.getProduct_image().put(id, productProject);
      }

      ////////////////////////////////////////tag
      sql = "select a.lid,a.tid,b.parent_id,channel from (select lid,tid from qyer_lastminute.zworld_lastminute_tag where isdel = 0) a join (select tag_id,parent_id,channel from qyer_lastminute.zworld_stype where status = 1 and type = 'stype') b on a.tid = b.tag_id;";
      pstmt = conn.prepareStatement(sql);
      rs = pstmt.executeQuery();
      while (rs.next()){

        id = rs.getInt(1);
        tid = rs.getInt(2);
        parentId = rs.getInt(3);
        channel = rs.getInt(4);
        stypes.add(parentId);
        stypes.add(tid);

        if(productSnapshot.getProduct_image().containsKey(id)) {
          ProductProject productProject = productSnapshot.getProduct_image().get(id);
          if (zTagEntityMap.containsKey(channel)) {
            Map<Integer, Map<Integer, VTYPEDES>> ztagMap = productProject.getZtagMap();
            Map<Integer, List<Integer>> stgFilter = zTagEntityMap.get(channel).getSTG_Filter();
            Map<Integer, List<Integer>> stFilter = zTagEntityMap.get(channel).getST_Filter();
            Map<Integer, Map<Integer, Set<Integer>>> stgLidList = productSnapshot.getStg_product();
            Map<Integer, Map<Integer, Set<String>>> stgStrList = productSnapshot.getStg_product_str();
            Map<Integer, Set<Integer>> stLidList = productSnapshot.getSt_product();
            Map<Integer, Set<String>> stStrList = productSnapshot.getSt_product_str();
            //maybe筛选项
            Set<Integer> integerSet = productProject.getMaybeTags();

            if(stgFilter.containsKey(parentId)) {
              List<Integer> stgs = stgFilter.get(parentId);
              for(int c:stgs){
                if(neFilterMap.containsKey(c))
                  integerSet.addAll(neFilterMap.get(c));
              }
            }
            /*else
              System.out.println("lid:"+id+";stg:"+parentId+";st:"+tid);*/
            if(stFilter.containsKey(tid)) {
              List<Integer> sts = stFilter.get(tid);
              for (int c : sts) {
                if (neFilterMap.containsKey(c))
                  integerSet.addAll(neFilterMap.get(c));
              }
            }
            ///加入大类列表
            if(stgLidList.containsKey(channel)){
              Map<Integer, Set<Integer>> map = stgLidList.get(channel);
              Map<Integer, Set<String>> map1 = stgStrList.get(channel);
              if(map.containsKey(parentId)){
                map.get(parentId).add(id);
                map1.get(parentId).add(String.valueOf(id));
              }else {
                Set<Integer> list = new HashSet<>(512);
                list.add(id);
                map.put(parentId, list);

                Set<String> set = new HashSet<>(512);
                set.add(String.valueOf(id));
                map1.put(parentId, set);
              }
            }else {
              Set<Integer> list = new HashSet<>(256);
              list.add(id);
              Map<Integer, Set<Integer>> map = new HashMap<>();
              map.put(parentId, list);
              stgLidList.put(channel, map);

              Set<String> set = new HashSet<>(256);
              set.add(String.valueOf(id));
              Map<Integer, Set<String>> map2 = new HashMap<>();
              map2.put(parentId, set);
              stgStrList.put(channel, map2);
            }
            if(stLidList.containsKey(tid)){
              stLidList.get(tid).add(id);
              stStrList.get(tid).add(String.valueOf(id));
            }else {
              Set<Integer> list = new HashSet<>();
              list.add(id);
              stLidList.put(tid,list);

              Set<String> set = new HashSet<>();
              set.add(String.valueOf(id));
              stStrList.put(tid,set);
            }
            /////////////////////////////////////////////////////////////

            if(ztagMap.containsKey(channel)){
              Map<Integer, VTYPEDES> innerZTag = ztagMap.get(channel);
              if(innerZTag.containsKey(parentId)){
                VTYPEDES vtypedes = innerZTag.get(parentId);
                if(stFilter.containsKey(tid)){
                  List<Integer> list = stFilter.get(tid);
                  for(int cid:list){
                    Set<Integer> set = new HashSet<>();
                    Map<Integer, Set<Integer>> map = new HashMap<>();
                    map.put(cid, set);
                    vtypedes.getST_FILTER_MAP().put(tid,map);////////////////////
                  }
                }else {
                  vtypedes.getST_FILTER_MAP().put(tid, new HashMap<Integer, Set<Integer>>());
                }
              }else {
                VTYPEDES vtypedes = new VTYPEDES();
                if (stgFilter.containsKey(parentId)) {
                  List<Integer> list = stgFilter.get(parentId);
                  for (int cid : list) {
                    Set<Integer> set = new HashSet<>();
                    vtypedes.getSTG_FILTER_MAP().put(cid, set);
                  }
                }
                //
                if (stFilter.containsKey(tid)) {
                  List<Integer> list = stFilter.get(tid);
                  for (int cid : list) {
                    Set<Integer> set = new HashSet<>();
                    Map<Integer, Set<Integer>> map = new HashMap<>();
                    map.put(cid, set);
                    vtypedes.getST_FILTER_MAP().put(tid, map);
                  }
                } else {
                  vtypedes.getST_FILTER_MAP().put(tid, new HashMap<Integer, Set<Integer>>());
                }
                ////put stg
                innerZTag.put(parentId, vtypedes);
              }
            }else {
              ////channel不存在

              VTYPEDES vtypedes = new VTYPEDES();
              if (stgFilter.containsKey(parentId)) {
                List<Integer> list = stgFilter.get(parentId);
                for (int cid : list) {
                  Set<Integer> set = new HashSet<>();
                  vtypedes.getSTG_FILTER_MAP().put(cid, set);
                }
              }
              //
              if (stFilter.containsKey(tid)) {
                List<Integer> list = stFilter.get(tid);
                for (int cid : list) {
                  Set<Integer> set = new HashSet<>();
                  Map<Integer, Set<Integer>> map = new HashMap<>();
                  map.put(cid, set);
                  vtypedes.getST_FILTER_MAP().put(tid, map);
                }
              } else {
                vtypedes.getST_FILTER_MAP().put(tid, new HashMap<Integer, Set<Integer>>());
              }

              Map<Integer, VTYPEDES> map = new HashMap<>();
              map.put(parentId, vtypedes);
              ztagMap.put(channel, map);
              /////////////////////////////////////////////////////////////////////////////////////////
            }
          ///////////////////////////
          }
        }
        ////
      }
      /////////////////////////////////////////////////////////////////////////////////////////
      sql = "select id,tag_name from  qyer_lastminute.zworld_tag where state = 1 and id in ( ";
      for(int tagID:stypes){
        sql += tagID;
        sql += ",";
      }
      sql += "-1);";
      pstmt = conn.prepareStatement(sql);
      rs = pstmt.executeQuery();
      while (rs.next()){
        id = rs.getInt(1);
        tagName = rs.getString(2);
        tagInfo.put(id, tagName);
      }
      /////////////////////////////////////////////////////////////////////////////////////////
      sql = "select tag_id,category_id,channel,type from (select id,tag_id,channel,type from qyer_lastminute.zworld_stype where status = 1) a join (select stype_id,category_id from qyer_lastminute.zworld_stype_category) b on a.id = b.stype_id;";
      pstmt = conn.prepareStatement(sql);
      rs = pstmt.executeQuery();
      while (rs.next()){
        tid = rs.getInt(1);
        category_id = rs.getInt(2);
        channel = rs.getInt(3);
        type = rs.getString(4);
        QuickSearch quickSearch = new QuickSearch(channel, type, tid);
        if(quickSearchMap.containsKey(category_id)){
          quickSearchMap.get(category_id).add(quickSearch);
        }else {
          List<QuickSearch> list = new ArrayList<>();
          list.add(quickSearch);
          quickSearchMap.put(category_id, list);
        }
      }
      //////////////////////////////////////筛选项tag///////////////////////////////////////////
      sql = "select lid,tid from qyer_lastminute.zworld_lastminute_tag where isdel = 0 and tid in ( ";
      for(int tagID:tags){
        sql += tagID;
        sql += ",";
      }
      sql += "-1);";
      pstmt = conn.prepareStatement(sql);
      rs = pstmt.executeQuery();
      while (rs.next()){
        id = rs.getInt(1);
        tid = rs.getInt(2);
        //////////////////////
        if(productSnapshot.getProduct_image().containsKey(id)) {
          ProductProject productProject = productSnapshot.getProduct_image().get(id);
          ////运营
          if (markets.contains(tid)) {
            String name = tagInfo.get(tid);
            try {
              productProject.setMarketInfo(Integer.parseInt(name));
            }catch (Exception e){
              e.printStackTrace();
            }
          }
          ////筛选tag
          if(filterTagMap.containsKey(tid)){

            Set<Integer> integerSet = productProject.getMaybeTags();
            if(integerSet.contains(tid)){
              Map<Integer, Map<Integer, VTYPEDES>> vMap = productProject.getZtagMap();
              List<Integer> list = filterTagMap.get(tid);
              for(int categoryId:list){
                List<QuickSearch> quickSearchList = quickSearchMap.get(categoryId);
                for(QuickSearch quickSearch:quickSearchList){
                  int ch = quickSearch.getChannel();
                  int td = quickSearch.getTagId();
                  String stype = quickSearch.getType();
                  if("stype".equals(stype)){
                    if(vMap.containsKey(ch)){
                      Map<Integer, List<Integer>> st_stg = zTagEntityMap.get(ch).getNegativeMap();
                      List<Integer> stg_st = st_stg.get(td);
                      Map<Integer, VTYPEDES> map = vMap.get(ch);
                      for(int stg_id:stg_st){
                        if(map.containsKey(stg_id)){
                          VTYPEDES vtypedes = map.get(stg_id);
                          if(vtypedes.getST_FILTER_MAP().containsKey(td)){
                            Map<Integer, Set<Integer>> setMap = vtypedes.getST_FILTER_MAP().get(td);
                            if(setMap.containsKey(categoryId)){
                              setMap.get(categoryId).add(tid);
                            }else {
                              System.out.println("异常:"+tid+";category:"+categoryId+";商品:"+id);
                            }
                          }
                        }
                      }
                    }
                  }else if("group".equals(stype)){
                    if(vMap.containsKey(ch)){
                      Map<Integer, VTYPEDES> vvMap =vMap.get(ch);
                      if(vvMap.containsKey(td)){
                        VTYPEDES vtypedes = vvMap.get(td);
                        if(vtypedes.getSTG_FILTER_MAP().containsKey(categoryId)) {
                          vtypedes.getSTG_FILTER_MAP().get(categoryId).add(tid);
                        }else {
                          System.out.println("异常:"+tid+";category:"+categoryId+";商品:"+id);
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
        //////////////////////
      }
      /////////////////////////////////////////////
      /*if(productSnapshot.getProduct_image().containsKey(81230)){
        System.out.println(productSnapshot.getProduct_image().get(50826));
        //80047
        System.out.println(productSnapshot.getProduct_image().get(81547));
        //77984
        System.out.println(productSnapshot.getProduct_image().get(77984));
        ////
        System.out.println(productSnapshot.getProduct_image().get(82476));

        System.out.println(productSnapshot.getProduct_image().get(82451));
      }*/
      //System.out.println(productSnapshot.getProduct_image().get(82451));
      /////////////poi信息
      int ll = allPoi.size();

      int j = 0;
      sql = "select id,chinesename from qyer.place_poi where id in (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);";
      pstmt = conn.prepareStatement(sql);
      while(j < ll) {
        for (int i = 0; i < 200; i++){
          if(j >= ll){
            pstmt.setInt((i+1), -1);
          }else {
            pstmt.setInt((i+1), allPoi.get(j));
          }
          j++;
        }
        rs = pstmt.executeQuery();
        while (rs.next()){
          id = rs.getInt(1);
          tagName = rs.getString(2);
          if(StringUtils.isNotEmpty(tagName))
            poiInfo.put(id, tagName);
        }
        pstmt.clearParameters();
      }
      //rs = pstmt.executeQuery();
      /////////////////////////////////大类筛选项///////////////////////////////
      Set<Integer> s1 = new HashSet<>();
      Set<Integer> s2 = new HashSet<>();
      if(back != null) {
        long h1 = System.currentTimeMillis();
        Map<Integer, Map<Integer, AggregationProduct>> mapMap = new HashMap<>();
        Map<Integer, Map<Integer, List<Type1SearchEntity>>> stg_entity = new HashMap<>();
        Map<Integer, Map<Integer, Set<String>>> strs = productSnapshot.getStg_product_str();
        Map<Integer, Map<Integer, Map<Integer, List<SearchEntity>>>> stg_sort_entity = new HashMap<>();
        Set<Integer> channelSet = zTagEntityMap.keySet();
        for (int chId : channelSet) {
          ZTagEntity zTagEntity = zTagEntityMap.get(chId);
          Set<Integer> stgSet = zTagEntity.getS_type_group_set();
          for (int stgId : stgSet) {
            Map<Integer, Set<Integer>> vTypeMap = new HashMap<>();
            List<Integer> stypeList = zTagEntity.getPositiveMap().get(stgId);
            Set<Integer> tmp = new HashSet<>(stypeList);
            vTypeMap.put(stgId, tmp);
            AggregationRegular regular = new AggregationRegular(vTypeMap, chId);
            AggregationProduct searchCensus = new AggregationProduct();
            Set<String> set = strs.get(chId).get(stgId);
            List<String> list;
            if(CollectionUtils.isNotEmpty(set)){
              list = new ArrayList<>(strs.get(chId).get(stgId));
            }else {
              list = new ArrayList<>();
              System.out.println("empty:" + stgId + ":" + chId);
            }
            List<Type1SearchEntity> entities = ModelUtils.packageBySTG(null, list, null, regular,
                                                                    searchCensus, 0);
            List<Type1SearchEntity> sortedEntities = new VType1Sorter2(null, entities, chId)
              .sort(s1, s2);
            searchCensus.sort();
            /*****************************************************************************/
            Type1SearchEntity type1SearchEntity = null;
            if(CollectionUtils.isNotEmpty(entities))
              type1SearchEntity = entities.get(0);
            List<SearchEntity> psortEntities = new VSalesTimSorterNoSize(null, type1SearchEntity, 1).sort();
            /*****************************************************************************/
            if (mapMap.containsKey(chId)) {
              mapMap.get(chId).put(stgId, searchCensus);
            } else {
              Map<Integer, AggregationProduct> map = new HashMap<>();
              map.put(stgId, searchCensus);
              mapMap.put(chId, map);
            }
            if (stg_entity.containsKey(chId)) {
              stg_entity.get(chId).put(stgId, sortedEntities);
            } else {
              Map<Integer, List<Type1SearchEntity>> map = new HashMap<>();
              map.put(stgId, sortedEntities);
              stg_entity.put(chId, map);
            }

            /***************************************************************************/
            if (stg_sort_entity.containsKey(chId)) {
              Map<Integer, Map<Integer, List<SearchEntity>>> chTypeEntitys = stg_sort_entity.get(chId);
              if(chTypeEntitys.containsKey(stgId)){
                chTypeEntitys.get(stgId).put(2, psortEntities);
              }else {
                Map<Integer, List<SearchEntity>> sortTypeEntitys = new HashMap<>();
                sortTypeEntitys.put(2, psortEntities);
                chTypeEntitys.put(stgId, sortTypeEntitys);
              }
            } else {
              Map<Integer, List<SearchEntity>> sortTypeEntitys = new HashMap<>();
              sortTypeEntitys.put(2, psortEntities);
              Map<Integer, Map<Integer, List<SearchEntity>>> chTypeEntitys = new HashMap<>();
              chTypeEntitys.put(stgId, sortTypeEntitys);
              stg_sort_entity.put(chId, chTypeEntitys);
            }
            /***************************************************************************/
          }
        }
        long h2 = System.currentTimeMillis();
        System.out.println("筛选项生成时间:" + (h2 - h1));
        productSnapshot.setStg_census(mapMap).setStg_entity(stg_entity);
        productSnapshot.setStg_sort_entity(stg_sort_entity);
      }
      /////////////////////////////////大类筛选项///////////////////////////////
      productSnapshot.setTagInfo(tagInfo);
      productSnapshot.setPoiInfo(poiInfo);

      //System.out.println("tagInfo:" + tagInfo);
      //System.out.println("poiInfo:" + poiInfo);
      System.out.println("Snapshot Size:" + productSnapshot.getProduct_image().size());

      DateTime dateTime=new DateTime();
      System.out.println("更新时间:"+ dateTime.toString("yyyy-MM-dd HH:mm:ss.SSSa"));
      //////////////////////////////////////////////////
    }catch (Exception e){
      e.printStackTrace();
      return back;
    }finally {
      closeQuietly(conn, pstmt, rs);
    }
    return productSnapshot;
  }
}
